package com.lynn.common.utils.file;

/**
 * DESC:
 * TIME:2019-08-05
 */
public class SizeConverterUtil {


    static String convertArbitrary(float size, boolean trim) {
        if (trim)
            return trimConvert(size, 0, false);
        else
            return converter(size, 0, false);
    }


     static String convertBytes(float B, boolean trim) {
        if (trim)
            return trimConvert(B, 0);
        else
            return converter(B, 0);
    }

     static String convertKB(float KB, boolean trim) {
        if (trim)
            return trimConvert(KB, 1);
        else
            return converter(KB, 1);
    }

     static String convertMB(float MB, boolean trim) {
        if (trim)
            return trimConvert(MB, 2);
        else
            return converter(MB, 2);
    }

     static String convertGB(float GB, boolean trim) {
        if (trim)
            return trimConvert(GB, 3);
        else
            return converter(GB, 3);
    }

     static String convertTB(float TB, boolean trim) {
        if (trim)
            return trimConvert(TB, 4);
        else
            return converter(TB, 4);
    }

     static String convertPB(float PB, boolean trim) {
        if (trim)
            return trimConvert(PB, 5);
        else
            return converter(PB, 5);
    }


///////////////////////////////////////////////////////////////////////////
// 私有方法
///////////////////////////////////////////////////////////////////////////

    private static String converter(float size, int unit) {
        return converter(size, unit, true);
    }


    /***
     *
     *  存储大小单位间的转换. 注意该方法的最大单位为PB, 最小单位为B,
     * 任何超出该范围的单位最终会显示为**.
     *
     * @param unit 从哪个单位开始
     * @param size 存储大小, 注意是float, 不要以整形的形式传入, 否则会溢出(如:1024*1024这种,
     * 它是先将1024*1024作为int相乘再转换为float的, 如果值过大的话就会溢出了,
     * 所以这么写1024.0F*1024.0F)
     *
     * @param withUnit 返回的结果字符串是否带有对应的单位
     */
    private static String converter(float size, int unit, boolean withUnit) {
        while (size > 1024) {
            unit++;
            size /= 1024f;
        }

        if (withUnit) {
            int index;
            if (unit < FileConst.LAST_IDX)
                index = unit;
            else
                index = FileConst.LAST_IDX;

            return String.format(
                    FileConst.LOCALE,
                    FileConst.FORMAT_F_UNIT, size, FileConst.UNITS[index]
            );
        }

        return String.format(FileConst.LOCALE,
                             FileConst.FORMAT_F, size
        );
    }


    private static String trimConvert(float size, int unit) {
        return trimConvert(size, unit, true);
    }


    /***
     *
     *  存储大小单位间的转换, 如果转换后小数部分为0, 则去除小数部分.
     * 注意该方法的最大单位为PB, 最小单位为B, 任何超出该范围的单位最终会显示为**.
     *
     * @param unit 从哪个单位开始
     * @param size 存储大小, 注意是float, 不要以整形的形式传入, 否则会溢出(如:1024*1024这种,
     * 它是先将1024*1024作为int相乘再转换为float的, 如果值过大的话就会溢出了,
     * 所以这么写1024.0F*1024.0F)
     *
     * @param withUnit 返回的结果字符串是否带有对应的单位
     */
    private static String trimConvert(float size, int unit, boolean withUnit) {

        while (size > 1024) {
            unit++;
            size /= 1024f;
        }

        int sizeInt = (int) size;
        boolean isfloat = size - sizeInt > 0.0f;

        if (withUnit) {
            int index;
            if (unit < FileConst.LAST_IDX)
                index = unit;
            else
                index = FileConst.LAST_IDX;


            if (isfloat) {
                return String.format(
                        FileConst.LOCALE,
                        FileConst.FORMAT_F_UNIT, size, FileConst.UNITS[index]
                );
            } else
                return String.format(
                        FileConst.LOCALE,
                        FileConst.FORMAT_D_UNIT, sizeInt, FileConst.UNITS[index]
                );
        }

        if (isfloat) {
            return String.format(
                    FileConst.LOCALE,
                    FileConst.FORMAT_F, size
            );
        } else
            return String.format(
                    FileConst.LOCALE,
                    FileConst.FORMAT_D, sizeInt
            );
    }


}
